package cn.lili.aop.interceptor;

import cn.hutool.core.thread.threadlocal.NamedThreadLocal;
import cn.lili.aop.annotation.AuthGoodsOpenLog;
import cn.lili.modules.goods_auth.service.GoodsAuthLogService;
import cn.lili.modules.system.entity.dos.LiAuthLog;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
import java.util.Map;
import java.util.Objects;

@Component
@Aspect
@Slf4j
public class AuthGoodsLogAspect {

    @Resource
    private GoodsAuthLogService goodsAuthLogService;

    private static final ThreadLocal<Long> TIME_THREADLOCAL=new NamedThreadLocal<>("costTime");

    @Pointcut("@annotation(cn.lili.aop.annotation.AuthGoodsOpenLog)")
    public void authGoodsLog(){}

    /**
     * 记录请求开始时间
     * 日志记录所需数据：请求参数、响应参数、类型、状态（成功or失败）、授权编号、授权id、请求时间、响应时间、响应时长、重试次数？
     * @param joinPoint
     */
    @Before("authGoodsLog()")
    public void saveAuthGoodsLog(JoinPoint joinPoint){
        TIME_THREADLOCAL.set(System.currentTimeMillis());
    }

    /**
     * 处理完请求执行
     * */
    @AfterReturning(value = "authGoodsLog()",returning = "res")
    public void doAfterReturning(JoinPoint joinPoint,Object res){
        handleLog(joinPoint,res,null);
    }

    /**
     * 执行异常时
     * */
    @AfterThrowing(value = "authGoodsLog()",throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint,Exception e){
        handleLog(joinPoint,null,e);
    }

    /**
     * 封装日志
     * */
    private void handleLog(final JoinPoint joinPoint,Object res, final Exception e) {
        if(res == null){
            return;
        }
        LiAuthLog authLog = new LiAuthLog();
        try {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            AuthGoodsOpenLog annotation = signature.getMethod().getAnnotation(AuthGoodsOpenLog.class);
            Object[] args = joinPoint.getArgs();
            //类型
            authLog.setType(annotation.OperateType());
            //获取请求参数
            authLog.setRequestContent(String.valueOf(args[0]));
            //sendTime
            authLog.setSendTime(new Date(TIME_THREADLOCAL.get()));
            //returnTime
            authLog.setReturnTime(new Date());
            //响应时长
            authLog.setReturnDuration(String.valueOf(System.currentTimeMillis()-TIME_THREADLOCAL.get()));

            //授权编号、授权id
            Map<String,Object> req=(Map<String,Object>)JSONObject.toJSON(args[0]);
            authLog.setAuthAppid(req.get("appid") == null ? null : req.get("appid").toString());
            authLog.setGoodsId(req.get("goodsId") == null ? null : req.get("goodsId").toString());

            //响应参数
            Map<String,Object>map= (Map<String,Object>)JSONObject.toJSON(res);

            if (map==null){
                authLog.setStatus("异常");
            }else {
                String message = JSONObject.toJSONString(map.get("message"));
                String jsonResult = JSONObject.toJSONString(map.get("result"));
                Map<String,Object> resultMap=(Map<String,Object>)map.get("result");
                if (Objects.equals(map.get("success"),true)){
                    authLog.setStatus("成功");
                    authLog.setFlag(resultMap.get("flag") + "");
                    authLog.setResponseContent(jsonResult);
                }
                else {
                    authLog.setStatus("失败");
                    authLog.setResponseContent(message);
                }
            }
        }catch (Exception exp){
            log.info("拉取商品日志异常:{}",exp.getMessage());
            authLog.setStatus("失败");
            authLog.setResponseContent(JSONObject.toJSONString(res));
        }finally {
            TIME_THREADLOCAL.remove();
            authLog.setRetryNumber(0L);
            goodsAuthLogService.save(authLog);
        }
    }
}

